//
// Created by hjie on 23-5-7.
//
#pragma once

#include <cstdint>
#include <map>
#include <string>
#include <iostream>
#include <memory>
#include <functional>
#include <atomic>
#include "redis_message_request.h"
#include "redis_message_reply.h"
#include "./../loop_event/loop_event_define.h"

using AsyncCallback = std::function<void(int status, const std::string & msg)>;

class RedisClient
{
public:
    RedisClient(LoopEvent * loop, const std::string & ip, uint16_t port);
    RedisClient(LoopEvent * loop, RedisOption & option);
    RedisClient(LoopEvent * loop);
    ~RedisClient();
    bool ConnectToRedis();
public:
    int64_t OperateCommand(const std::string & msg);
    RedisMessageResponse * GetReplyByIndex(int64_t index);
    void FreeReplyByIndex(int64_t index);

    void OnMessage(const uint8_t * msg, int length);
    bool DecoderMsg(const uint8_t * data, int length, int & use_data_size);

    bool CheckClientStatus();
    void OnConnection();
    void OnDisconnection(int code);
    void CloseClient();
private:
    bool CheckOption();
    void RelaseAllResponse();
private:
    LoopEvent  * m_loop_event;
    Client     * m_connection_client;
    std::atomic<bool> m_client_status;
private:
    RedisOption m_option;
private:
    std::mutex m_mtx; // single thread process
    int64_t m_index{0};
    std::map<int64_t, RedisMessageResponse*> m_response_map;
    std::map<int64_t, RedisMessageResponse*>::iterator m_current_iter;
};



